package com.example.blog_system_ssm.component;

import com.example.blog_system_ssm.common.Constant;
import com.example.blog_system_ssm.common.SensitiveWordUtil;
import com.example.blog_system_ssm.mapper.SensitiveWordMapper;
import com.example.blog_system_ssm.service.ArticleService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.Ordered;
import org.springframework.core.annotation.Order;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
import java.util.List;
import java.util.Set;

//实现Redis和MySQL数据库的数据交换
//实现敏感词过滤初始化
@Slf4j
@Component
@Order(Ordered.HIGHEST_PRECEDENCE)
@EnableScheduling
public class ListenHandler {
    @Autowired
    private RedisTemplate<String, Object> redisTemplate;
    private final ArticleService articleService;
    private final RedisUtil redisUtil;
    @Autowired
    private SensitiveWordMapper sensitiveWordMapper;
    @Autowired
    private SensitiveWordUtil sensitiveWordUtil;

    @Autowired
    public ListenHandler(ArticleService articleService, RedisUtil redisUtil) {
        this.articleService = articleService;
        this.redisUtil = redisUtil;
    }
    //启动时执行
    @PostConstruct
    public void initRedis() throws Exception{
        log.info("redis数据初始化开始...");
        //清空redis中数据，防止之前的数据影响
        List<Long> aids=articleService.getAllId();
        for(Long aid:aids){
            redisTemplate.opsForHyperLogLog().delete(Constant.RCOUNT_ARTICLE_ID +aid);
        }
        log.info("数据已清除...");
    }
    @PostConstruct
    public void intiSensitiveWord(){
        log.info("敏感词数据初始化开始...");
        Set<String> sensitiveWordSet=sensitiveWordMapper.getAll();
        sensitiveWordUtil.init(sensitiveWordSet);
        log.info("敏感词数据初始化完成...");
    }
    //关闭前执行
    @PreDestroy
    public void afterDestroy() {
        log.info("开始关闭...");
        //将redis中的数据写入数据库
        List<Long> aids=articleService.getAllId();
        for(Long aid:aids){
            int incr= Math.toIntExact(redisTemplate.opsForHyperLogLog().size(Constant.RCOUNT_ARTICLE_ID+aid));
            articleService.incrNumById(aid,incr);
        }
        log.info("redis写入数据库完毕");
    }

    //30分钟执行一次
    @Scheduled(cron = "0 0/30 * * * ?")
    public void updateNum() {
        log.info("周期任务开始执行...");
        // TODO: 2023/2/4 消息队列优化 
        List<Long> aids=articleService.getAllId();
        for(Long aid:aids){
            int incr= Math.toIntExact(redisTemplate.opsForHyperLogLog().size(Constant.RCOUNT_ARTICLE_ID+aid));
            articleService.incrNumById(aid,incr);
            //清除redis数据
            redisTemplate.opsForHyperLogLog().delete(Constant.RCOUNT_ARTICLE_ID+aid);
        }
        log.info("周期任务执行完毕,redis写入数据库完毕");
    }
}
